﻿////Copyright 2011 - Jonathan Allen

//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.ComponentModel;

//namespace Granite.Modeling.Internals
//{
//	/// <summary>
//	/// Property bag with multi-level change tracking capabilities.
//	/// </summary>
//	public class MultilevelPropertyBag : ChangeTrackingPropertyBag
//	{
//		readonly Stack<Dictionary<string, object>> m_CheckpointStack = new Stack<Dictionary<string, object>>();

//		/// <summary>
//		/// Property bag with multi-level change tracking capabilities.
//		/// </summary>
//		/// <param name="owner"></param>
//		public MultilevelPropertyBag(object owner) : base(owner) { }


//		/// <summary>
//		/// This creates a checkpoint using the current values. The checkpoint remains available until EndEdit or CancelEdit is called.
//		/// </summary>
//		/// <remarks>Calling this method multiple times will create multiple checkpoints.</remarks>
//		public void BeginEdit()
//		{
//			var checkpoint = new Dictionary<string, object>(StringComparer.Ordinal);

//			foreach (var item in Values)
//			{
//				checkpoint.Add(item.Key, item.Value);
//				if (item.Value is IEditableObject)
//					((IEditableObject)item.Value).BeginEdit();
//			}

//			m_CheckpointStack.Push(checkpoint);

//		}

//		/// <summary>
//		/// This reverts all changes to the checkpoint values. CancelEdit is called recursively on any value in the original list. 
//		/// </summary>
//		/// <remarks>Calling this when there are no matching BeginEdit will have no effect.</remarks>
//		public void CancelEdit()
//		{
//			if (m_CheckpointStack.Count == 0)
//				return;

//			var checkpoint = m_CheckpointStack.Pop();

//			//remove properties that no longer exist
//			foreach (var item in Values.ToList())
//			{
//				if (!checkpoint.ContainsKey(item.Key))
//				{
//					Values.Remove(item.Key);
//					OnPropertyChanged(item.Key);
//					OnRevalidateProperty(item.Key);
//				}
//			}

//			//update remaining properties
//			foreach (var item in checkpoint)
//			{
//				var oldValue = GetValue(item.Key);
//				if (!object.Equals(oldValue, item.Value))
//				{
//					Values[item.Key] = item.Value;
//					OnPropertyChanged(item.Key);
//					OnRevalidateProperty(item.Key);
//				}
//			}

//			//recusively call CancelEdit			
//			foreach (var item in checkpoint)
//			{
//				if (item.Value is IEditableObject)
//					((IEditableObject)item.Value).CancelEdit();
//			}

//			OnRevalidateObject();
//		}

//		/// <summary>
//		/// This removed one level of checkpoint values. EndEdit is called recursively on any value in the list of cheeckpoint values. Since this class didn't call BeginEdit on the new values, it will not call EndEdit on them either.
//		/// </summary>
//		/// <remarks>Calling this when there are no matching BeginEdit will have no effect.</remarks>
//		public void EndEdit()
//		{
//			if (m_CheckpointStack.Count == 0)
//				return;

//			var checkpoint = m_CheckpointStack.Pop();

//			foreach (var item in checkpoint)
//			{
//				if (item.Value is IEditableObject)
//					((IEditableObject)item.Value).EndEdit();
//			}
//		}

//		/// <summary>
//		/// This indicates how many unmatched BeginEdit class are currently being tracked.
//		/// </summary>
//		public int EditDepth
//		{
//			get { return m_CheckpointStack.Count; }
//		}

//		/// <summary>
//		/// Marks all fields as unchanged by storing them in the original values collection.
//		/// </summary>
//		/// <remarks>Calling this ends all pending edits.</remarks>
//        public override void AcceptChanges(bool recursive)
//		{
//			while (EditDepth > 0)
//				EndEdit();
//            base.AcceptChanges(recursive);
//		}

//		/// <summary>
//		/// Replaces the current values collection with the original values collection.
//		/// </summary>
//		/// <remarks>Calling this cancels all pending edits.</remarks>
//        public override void RejectChanges(bool recursive)
//		{
//			while (EditDepth > 0)
//				CancelEdit();
//            base.RejectChanges(recursive);
//		}

//	}
//}
